package com.nm.orm.dao.impl;

import com.nm.commons.exception.SupperException;
import com.nm.commons.util.StringUtil;
import com.nm.orm.convert.ArticleConvert;
import com.nm.orm.dao.ArticleDao;
import com.nm.orm.dao.model.ArticleDaoModel;
import com.nm.orm.dao.pageParam.ArticleBackPageInput;
import com.nm.orm.model.State;
import com.nm.orm.param.Page.Op;
import com.nm.orm.pojo.ArticleEntity;
import com.nm.orm.pojo.out.ArticleBackPageOutput;
import com.nm.service.page.PageEntity;
import com.nm.web.util.JsonHelper;
import org.apache.commons.collections.MapUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by hewu on 2017/2/15 0015.
 */
@Repository
@Qualifier("articlesDao")
public class ArticleDaoImpl extends DaoImpl<ArticleEntity, String> implements ArticleDao, ArticleDaoModel {


    public ArticleDaoImpl() {
        super(ArticleEntity.class);
    }


    @Override
    public List<ArticleEntity> findAll() throws SupperException {
        Criteria criteria = getCurrentSession(sessionFactory)
                .createCriteria(ArticleEntity.class)
                .addOrder(Order.desc(UPDATE_AT))
                .add(Restrictions.eq(STATUS, State.ABLE.dbValue()));

        return criteria.list();
    }

    //    /**
//     * 前台分页查询
//     *
//     * @param input
//     * @return
//     */
//    @Override
    public PageEntity<ArticleBackPageOutput> backPage(ArticleBackPageInput input) {
        Map params = JsonHelper.toMap(input);
        StringBuffer hqlBuffer = new StringBuffer("select a ");
        StringBuffer chqBuffer = new StringBuffer("select count(a.id) ");

        StringBuffer fromHql = new StringBuffer();
        fromHql.append("from ArticleEntity a");

        if (!MapUtils.isEmpty(params)) {

            if (!StringUtil.isNull(input.getLabelId())) {
                fromHql.append(" left join  a.artLabelRefs lr");
            }

            if (params.size() - 2 > 0) {
                fromHql.append(" where ");
            }

            //加参数
            if (!StringUtil.isNull(input.getCategoryId())) {
                fromHql.append(" a.category.id ").append(Op.EQ.val()).append(CATEGORY_ID);
            }

            if (!StringUtil.isNull(input.getLabelId())) {
                isContinue(params.size() - 2, 1, fromHql);
                fromHql.append(" lr.label.id ").append(Op.EQ.val()).append(LABEL_ID);
            }
        }

        String order = " order by a.updatedAt ";

        String dhql = hqlBuffer.append(fromHql).append(order).toString();
        String chql = chqBuffer.append(fromHql).toString();

        Query dquery = getCurrentSession(sessionFactory).createQuery(dhql);

        Query cquery = getCurrentSession(sessionFactory).createQuery(chql);

        dquery.setMaxResults(input.getPage());
        dquery.setFirstResult(0);
        //分页参数处理
        paramHandle(params, dquery, cquery);

        //数据转换器
//        dquery.setResultTransformer(new ToListResultTransformer())

        List<ArticleEntity> articles = dquery.list();
        int totalSize = ((Long) cquery.iterate().next()).intValue();

        PageEntity<ArticleBackPageOutput> pageEntity = new PageEntity<ArticleBackPageOutput>();
        pageEntity.setData(ArticleConvert.conv(articles));
        pageEntity.setPageIndex(input.getPage());
        pageEntity.setTotalSize(totalSize);
        pageEntity.setPageSize(input.getRows());

        return pageEntity;

    }

    /**
     * 文章后台分页查询
     *
     * @param input
     * @return
     */
//    public PageEntity<ArticleBackPageOutput> backPage(ArticleBackPageInput input) {
//        Map params = JsonHelper.toMap(input);
//        StringBuffer sql = new StringBuffer();
//
//        sql.append(" from article as a left join ");
//        sql.append(" user as u on a.userId = u.id left join  category as c on a.categoryId = c.id ");
//        sql.append("left join  ( select re.id, re.articleId , re.labelId from article_label_ref  as re ");
//
//        if (!MapUtils.isEmpty(params)) {
//            if (!StringUtil.isNull(input.getLabelId())) {
//                sql.append(" where re.labelId = :labelId ");
//            }
//        }
//        sql.append(") as ref on ref.articleId = a.id ");
//        sql.append(" inner join label as l on ref.labelId = l.id ");
//
//        if (!MapUtils.isEmpty(params)) {
//            if (!StringUtil.isNull(input.getCategoryId())) {
//                sql.append("  and a.categoryId  = :categoryId ");
//            }
//        }
//
//        String order = "  order by a.updated_at ";
//
//        String dhql = new StringBuffer("select distinct a.* ").append(sql).toString();
//        String chql = new StringBuffer("select distinct count(a.id)").append(sql).toString();
//
//        Query dquery = getCurrentSession(sessionFactory).createSQLQuery(dhql).addEntity(ArticleBasic.class);
//
//        Query cquery = getCurrentSession(sessionFactory).createSQLQuery(chql);
//
//        dquery.setMaxResults(input.getPage());
//        dquery.setFirstResult(firstIndex(input.getPage(), input.getRows()));
//
//        //分页参数处理
//        pageParamHandle(params, dquery, cquery);
//
////        dquery.setResultTransformer(new AliasToBeanResultTransformer(ArticleBasic.class));
//        List<ArticleBasic> articles = dquery.list();
//        List<BigInteger> cResult = cquery.list();
//        int totalSize = cResult.get(0).intValue();
//
//        return new PageEntity<ArticleBackPageOutput>();
//    }
//    /**
//     * 文章后台分页查询
//     *
//     * @param input
//     * @return
//     */
//    public PageEntity<ArticleBackPageOutput> backPage(ArticleBackPageInput input) {
//        Map params = JsonHelper.toMap(input);
//        Criteria dataCriteria = getCurrentSession(sessionFactory)
//                .createCriteria(ArticleLabelRefEntity.class);
//
//        if (!MapUtils.isEmpty(params)) {
//            if (!StringUtil.isNull(input.getCategoryId())) {
//                dataCriteria.createAlias("article", "a");
//                dataCriteria.add(Restrictions.eq("a.category.id", input.getCategoryId()));
//            }
//            if (!StringUtil.isNull(input.getLabelId())) {
//                dataCriteria.createAlias("label", "l");//别名
//                dataCriteria.add(Restrictions.eq("l.id", input.getLabelId()));
//            }
//        }
//        //先查询总记录数
//        Long totalSize = (Long) dataCriteria.setProjection(Projections.rowCount())
//                .uniqueResult();
//        //置空projection
//        dataCriteria.setProjection(null);
//        //去重
////        dataCriteria.setProjection(Projections.distinct(Projections.property("a.id")));
//        //查真实数据
//        List<ArticleLabelRefEntity> list = dataCriteria
//                .setFirstResult(firstIndex(input.getPage(), input.getRows()))
//                .setMaxResults(input.getRows()).list();
//
//        //查询结果处理
//        PageEntity<ArticleBackPageOutput> pageEntity = new PageEntity<ArticleBackPageOutput>();
//        pageEntity.setPageSize(input.getRows());
//        pageEntity.setTotalSize(null == totalSize ? 0 : totalSize.intValue());
//
//        List<ArticleBackPageOutput> out = new ArrayList<ArticleBackPageOutput>();
//        for (ArticleLabelRefEntity refs : list) {
//            ArticleBackPageOutput backOut = new ArticleBackPageOutput();
//            backOut.setId(refs.getArticle().getId());
//            backOut.setArticleContent(refs.getArticle().getContent());
//            backOut.setArticleName(refs.getArticle().getName());
//            backOut.setCategory(new ArticleInnerCategoryOutput(
//                    refs.getArticle().getCategory().getId(), refs.getArticle().getCategory().getName()));
//            backOut.setHit(refs.getArticle().getHit());
////            backOut.setLabels(refs.getArticle().getArtLabelRefs());//标签处理
//            backOut.setUser(new ArticleInnerUserOutput(refs.getArticle().getUser().getId(),
//                    refs.getArticle().getUser().getName()));
//            out.add(backOut);
//        }
//        pageEntity.setData(out);
//        return pageEntity;
//    }

    /**
     * @param fix   除分页参数page、rows外的其他参数个数
     * @param index 查询参数记录下标
     * @param hql   sql的StringBuffer对象
     */
    private static void isContinue(int fix, int index, StringBuffer hql) {
        if (index < fix) {
            hql.append(" and ");
        }
    }

    /**
     * 分页参数处理
     *
     * @param map    参数map
     * @param dquery 数据查询query
     * @param cquery 记录数查询query
     */
    private static void pageParamHandle(Map map, Query dquery, Query cquery) {
        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry<String, Object> param = iterator.next();
            if (param.getKey().equals("labelId") && !StringUtil.isNull(String.valueOf(param.getValue()))) {
                String labelId = String.valueOf(param.getValue());
                dquery.setParameter("labelId", labelId);
                cquery.setParameter("labelId", String.valueOf(param.getValue()));
            }

            if (param.getKey().equals("categoryId") && !StringUtil.isNull(String.valueOf(param.getValue()))) {
                dquery.setParameter("categoryId", param.getValue());
                cquery.setParameter("categoryId", param.getValue());
            }

        }
    }

    /**
     * 分页参数处理
     *
     * @param map    参数map
     * @param dquery 数据查询query
     * @param cquery 记录数查询query
     */
    private static void paramHandle(Map map, Query dquery, Query cquery) {
        Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
        dquery.setProperties(map);
        cquery.setProperties(map);
    }


    public static int firstIndex(int page, int rows) {

        return page == 1 ? 0 : (page - 1) * rows + 1;
    }


}
